package com.android.dialer.extendboard;

import android.os.Parcelable;

import android.support.annotation.NonNull;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;


public class USBMessage implements Parcelable {
    private static final short MAGIC_NUMBER = (short) 0xABAB;
    private static final int HEADER_SIZE = 5; // 2 bytes for magic number, 1 byte for type, 2 byte for length

    private final short magicNumber;
    private final int messageType;
    private int length;
    private byte[] data;

    // add message type constants
    public static final int MESSAGE_TYPE_KEY_EVENT = 1;
    public static final int MESSAGE_TYPE_HOOK_STATE = 2;
    public static final int MESSAGE_TYPE_CONTROL = 102;
    public static final int MESSAGE_TYPE_CONFIG = 101;
    public static final int MESSAGE_TYPE_GET_HOOK_STATE = 103;
    public static final int MESSAGE_TYPE_SWITCH_MIC_STATE = 104;

    // Parcelable implementation
    public static final Creator<USBMessage> CREATOR = new Creator<USBMessage>() {
        @Override
        public USBMessage createFromParcel(android.os.Parcel in) {
            return new USBMessage(in);
        }

        @Override
        public USBMessage[] newArray(int size) {
            return new USBMessage[size];
        }
    };

    protected USBMessage(android.os.Parcel in) {
        magicNumber = (short) in.readInt();
        messageType = in.readInt();
        length = in.readInt();

        if (length > 0) {
            data = new byte[length];
            in.readByteArray(data);
        } else {
            data = null;
        }
    }
    @Override
    public int describeContents() { return 0; }


    public USBMessage(int messageType) {
        this.magicNumber = MAGIC_NUMBER;
        this.messageType = messageType;
        this.length = 0;
        this.data = null;
    }
    @Override
    public void writeToParcel(android.os.Parcel dest, int flags) {
        dest.writeInt(magicNumber);
        dest.writeInt(messageType);
        dest.writeInt(length);
        if (data != null) {
            dest.writeByteArray(data);}
    }

    public void setData(byte[] data) {
        this.data = data;
        if (data != null) {
            this.length = data.length;
        }else {
            this.length = 0;
        }
    }

    public USBMessage(int messageType, byte[] data) {
        this.magicNumber = MAGIC_NUMBER;
        this.messageType = messageType;
        this.length = data.length;
        this.data = data;
    }

    public byte[] toByteArray() {
        ByteBuffer buffer = ByteBuffer.allocate(5 + length).order(ByteOrder.LITTLE_ENDIAN);
        buffer.putShort(magicNumber);
        buffer.put((byte) messageType);

        buffer.putShort((short) length);
        if (length > 0) {
            buffer.put(data);
        }
        return buffer.array();
    }

    @NonNull
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("USBMessage{");
        sb.append("magicNumber=").append(magicNumber);
        sb.append(", messageType=").append(messageType);
        sb.append(", length=").append(length);
        sb.append(", data=");
        if (data != null) {
            for (byte b : data) {
                sb.append(String.format("%02X ", b));
            }
        } else {
            sb.append("null");
        }
        sb.append('}');
        return sb.toString();
    }

    public int getLength() {
        return length;
    }

    public int getMessageType() {
        return messageType;
    }

    public byte[] getData() {
        return data;
    }
}
